#include "RingQueue.hpp"
#include <unistd.h>
#include <cstdlib>
void *Product(void *args)
{
    RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);

    while (true)
    {
        // 1.生产数据
        int tem = (rand() ^ pthread_self()) % 37;
        // 2.加入环形队列（访问临界资源）
        rq->Push(tem);
        cout << "Product num : " << tem << endl;
        sleep(1);
        // usleep(100000);
    }
    return nullptr;
}

void *Consume(void *args)
{
    RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);

    while (true)
    {
        // 1.拿到数据（访问临界资源）
        int get;
        rq->Pop(&get);
        // 2.处理数据
        cout << "Consumer get :" << get << endl;
        //usleep(110000);
    }
    return nullptr;
}

void test1()
{
    cout << "main thread started ---pid:" << getpid() << endl;
    srand((unsigned int)time(nullptr));

    RingQueue<int> *rq = new RingQueue<int>(10);

    // 创建线程
    pthread_t p, c;
    pthread_create(&p, nullptr, Product, (void *)rq);
    pthread_create(&c, nullptr, Consume, (void *)rq);

    while (1)
    {
        cout << "队列内数据个数:" << rq->GetSize() << endl;
        sleep(1);
    }

    // 等待线程
    pthread_join(p, nullptr);
    pthread_join(c, nullptr);
}
void test2()
{
    cout << "main thread started ---pid:" << getpid() << endl;
    srand((unsigned int)time(nullptr));

    RingQueue<int> *rq = new RingQueue<int>(10);

    // 创建多个生产者消费者
    pthread_t p1, c1;
    pthread_t p2, c2;
    pthread_t p3, c3;
    pthread_t p4, c4;

    pthread_create(&p1, nullptr, Product, (void *)rq);
    pthread_create(&p2, nullptr, Product, (void *)rq);
    pthread_create(&p3, nullptr, Product, (void *)rq);
    pthread_create(&p4, nullptr, Product, (void *)rq);

    pthread_create(&c1, nullptr, Consume, (void *)rq);
    pthread_create(&c2, nullptr, Consume, (void *)rq);
    pthread_create(&c3, nullptr, Consume, (void *)rq);
    pthread_create(&c4, nullptr, Consume, (void *)rq);

    while (1)
    {
        cout << "队列内数据个数:" << rq->GetSize() << endl;
        sleep(1);
    }

    // 等待线程
    pthread_join(p1, nullptr);
    pthread_join(p2, nullptr);
    pthread_join(p3, nullptr);
    pthread_join(p4, nullptr);

    pthread_join(c1, nullptr);
    pthread_join(c2, nullptr);
    pthread_join(c3, nullptr);
    pthread_join(c4, nullptr);
}

int main()
{
    // 测试单生产单消费
    //  test1();

    // 测试多生产多消费
    test2();

    return 0;
}